class LrcParserFactory {
  static createParserByFileName(filename) {
    if (filename.indexOf(".bph") != -1) {
      return new BphLrcParser();
    } else if (filename.indexOf('.kas') != -1) {
      return new KasLrcParser();
    } else if (filename.indexOf('.txt') != -1) {
      return new KrcLrcParser();
    }
  }
}

class LrcParser {
  parse(content) {
    throw new Error("parser not implemented");
  }
}

class BphLrcParser extends LrcParser {
  parse(content) {
    let lrc = {"sentences": []};
    let list = content.split("[");
    for (var i = 0; i < list.length; i++) {
      let line = list[i];
      let i1 = line.indexOf(",");
      let i2 = line.indexOf("]");
      let i3 = line.indexOf("(");
      let i4 = line.indexOf(")");
      if (i1 != -1 && i1 < i2 && i2 < i3 && i3 < i4) {
        lrc["sentences"].push(this.parseLine(line));
      }
      
    }
    return lrc;
  } 
  parseLine(line) {
    let sentence = {};

    let tmp = line.substring(0, line.indexOf(']'));
    let tmp2 = tmp.split(",");

    sentence["timestamp"] = parseInt(tmp2[0]);
    sentence["duration"] = parseInt(tmp2[1]);
    tmp2 = line.substring(line.indexOf(']') + 1).split(")");
    sentence["slices"] = [];
    for (var i = 0; i < tmp2.length; i++) {
      let slice = {};
      if (tmp2[i].indexOf("(") == -1 || tmp2[i].indexOf(",") == -1) {
        break;
      }
      let occurTimes = this.getOccurTimes(tmp2[i], ",");
      if (occurTimes > 1) {
        for (var j = 1; j < occurTimes; j++) {
          tmp2[i] = tmp2[i].replace(", ", "， ");
        }
      }
      slice["word"] = tmp2[i].substring(0, tmp2[i].indexOf("("));
      slice["timestamp"] = parseInt(tmp2[i].substring(tmp2[i].indexOf("(") + 1, tmp2[i].indexOf(",")));
      slice["duration"] = parseInt(tmp2[i].substring(tmp2[i].indexOf(",") + 1));
      sentence["slices"].push(slice);
    }
    return sentence;
  }

  getOccurTimes(content, a) {
    let pos = -2;
    let n = 0;
    while (pos != -1) {
      if (pos == -2) {
        pos = -1;
      }
      pos = content.indexOf(a, pos + 1);
      if (pos != -1) {
        n++;
      }
    }
    return n;
  } 
}

class KasLrcParser extends LrcParser {
  parse(content) {
    let lrc = {"sentences":[]};
    let rows = content["lyrics"]["rows"];
    for (var i = 0; i < rows.length; i++) {
      let sentence = {"slices": []};
      sentence["timestamp"] = parseInt(rows[i]["start_time"]);
      sentence["duration"] = 0;
      let words = rows[i]["lyric"]["element"];
      for (var j = 0; j < words.length; j++) {
        let word = words[j];
        if (word.hasOwnProperty("string")) {
          let slice = sentence["slices"][sentence["slices"].length -1];
          slice["word"] += word["string"];
          continue;
        }
        sentence["duration"] += parseInt(word["duration"]);
        let slice = {"word": ""};
        slice["duration"] = word["duration"];
        slice["timestamp"] = sentence["timestamp"];
        if (word.hasOwnProperty("offset_time")) {
          slice["timestamp"] += parseInt(word["offset_time"]);
        }
        if (j > 0) {
          let last = sentence["slices"].length - 1;
          sentence["slices"][last]["duration"] = slice["timestamp"] - sentence["slices"][last]["timestamp"];
        }
        slice["word"] = word["words"];
        sentence["slices"].push(slice);
      }
      let last = sentence["slices"].length - 1;
      sentence["duration"] = sentence["slices"][last]["timestamp"] + sentence["slices"][last]["duration"] - sentence["timestamp"];
      lrc["sentences"].push(sentence);
    }

    return lrc;
  }

}

class KrcLrcParser {
  parse(content) {
    let lrc = {"sentences": []};
    let list = content.split("[");
    for (var i = 0; i < list.length; i++) {
      let line = list[i];
      var i1 = line.indexOf(",");
      var i2 = line.indexOf("]");
      var i3 = line.indexOf("<");
      var i4 = line.indexOf(">");

      if (i1 != -1 && i1 < i2 && i2 < i3 && i3 < i4) {
        lrc["sentences"].push(this.parseLine(line));
      }
    }
    return lrc;
  }

  parseLine(line) {
    let sentence = {"slices":[]};
    let tmp = line.substring(0, line.indexOf(']'));
    let tmp2 = tmp.split(",");
    sentence["timestamp"] = parseInt(tmp2[0]);
    sentence["duration"] = parseInt(tmp2[1]);

    tmp2 = line.substring(line.indexOf("<") + 1).split("<");
    for (var i = 0; i < tmp2.length; i++) {
      let slice = {};
      if (tmp2[i].indexOf(">") == -1 || tmp2[i].indexOf(",") == -1) {
        break;
      }
      slice["word"] = tmp2[i].substring(tmp2[i].indexOf(">") + 1);
      let tmp3 = tmp2[i].split(",");
      slice["timestamp"] = parseInt(tmp3[0]) + sentence["timestamp"];
      slice["duration"] = parseInt(tmp3[1]);
      if (i > 0) {
        sentence["slices"][i - 1]["duration"] = slice["timestamp"] - sentence["slices"][i-1]["timestamp"];
      }
      sentence["slices"].push(slice);
    }
    var last = sentence["slices"].length - 1;
    sentence["duration"] = sentence["slices"][last]["timestamp"] + sentence["slices"][last]["duration"] - sentence["timestamp"];

    return sentence;
  }

}

module.exports = {
  LrcParserFactory: LrcParserFactory,
  LrcParser: LrcParser,
}